package orders

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"github.com/shopspring/decimal"
	"github.com/spf13/cast"
	"insighttracking/common/utils"
	"insighttracking/query/bo"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"net/http"

	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type ModifyOrderByIdApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewModifyOrderByIdApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *ModifyOrderByIdApiLogic {
	hostname, _ := os.Hostname()
	return &ModifyOrderByIdApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *ModifyOrderByIdApiLogic) ModifyOrderByIdApi(req *types.ModifyOrderReq) (resp string, err error) {
	enterpriseId := cast.ToInt64(l.ctx.Value("enterpriseId"))
	_, err = dao.OrdersEntity.WithContext(l.ctx).Where(dao.OrdersEntity.ID.Eq(req.Id), dao.OrdersEntity.EnterpriseID.Eq(enterpriseId)).First()
	if err != nil {
		return "", errors.New("传递的采购单号错误")
	}
	if req.OrdersDetailList == nil || len(req.OrdersDetailList) == 0 {
		return "", errors.New("请传递商品信息")
	}
	// 1.判断金额是否正确
	spuIdList := k.Map(req.OrdersDetailList, func(item types.CreateOrdersDetailReq, index int) int64 {
		return item.SpuID
	})
	// 获取当前单价
	var spuEntities = make([]*bo.SpuBo, 0)
	if err = dao.SpuEntity.WithContext(l.ctx).Where(dao.SpuEntity.ID.In(spuIdList...)).Select(
		dao.SpuEntity.ALL,
		dao.UnitEntity.Name.As("UnitName"),
		dao.BrandEntity.Name.As("BrandName"),
		dao.SupplierEntity.Name.As("SupplierName"),
		dao.ProductionLineEntity.Name.As("ProductionLineName"),
	).
		LeftJoin(dao.UnitEntity, dao.UnitEntity.ID.EqCol(dao.SpuEntity.UnitID)).
		LeftJoin(dao.BrandEntity, dao.BrandEntity.ID.EqCol(dao.SpuEntity.BrandID)).
		LeftJoin(dao.SupplierEntity, dao.SupplierEntity.ID.EqCol(dao.SpuEntity.SupplierID)).
		LeftJoin(dao.ProductionLineEntity, dao.ProductionLineEntity.ID.EqCol(dao.SpuEntity.ProductionLineID)).
		Scan(&spuEntities); err != nil {
		return "", errors.New("传递的商品id错误")
	}

	spuPriceMap := k.ToMap(spuEntities, func(item *bo.SpuBo) (int64, decimal.Decimal) {
		return item.ID, item.SalesPrice
	})
	spuMap := k.ToMap(spuEntities, func(item *bo.SpuBo) (int64, *bo.SpuBo) {
		return item.ID, item
	})
	var totalCount = decimal.Zero
	var totalAmount = decimal.Zero
	for _, item := range req.OrdersDetailList {
		price, _ := decimal.NewFromString(item.SnapshotPrice)
		spuCount, _ := decimal.NewFromString(item.SpuCount)
		fmt.Println(price, "单价", spuCount, "---", spuPriceMap, "??", k.MapToString(item))
		if !spuCount.Mul(price).Equal(spuCount.Mul(spuPriceMap[item.SpuID])) {
			logx.Errorf("创建订单失败:%d,单价错误", item.SpuID)
			return "", errors.New(fmt.Sprintf("商品%d单价传递错误", item.SpuID))
		}
		// 计算总金额和总数量
		totalCount = totalCount.Add(spuCount)
		totalAmount = totalAmount.Add(spuCount.Mul(spuPriceMap[item.SpuID]))
	}
	tx := dao.Use(l.svcCtx.MysqlDb).Begin()
	if _, err = dao.OrdersEntity.WithContext(l.ctx).Where(dao.OrdersEntity.ID.Eq(req.Id)).UpdateSimple(
		dao.OrdersEntity.Remark.Value(req.Remark),                                        // 订单备注
		dao.OrdersEntity.TotalAmount.Value(totalAmount),                                  // 订单金额
		dao.OrdersEntity.TotalCount.Value(totalCount),                                    // 订单商品数量
		dao.OrdersEntity.SendGoodsDate.Value(utils.DateTimeStrToTime(req.SendGoodsDate)), // 发货日期
		dao.OrdersEntity.SettlementMethod.Value(req.SettlementMethod),                    // 结算方式
		dao.OrdersEntity.SendGoodsMethod.Value(req.SendGoodsMethod),                      // 配送方式
		dao.OrdersEntity.PurchaserID.Value(req.PurchaserId),                              // 采购员
	); err != nil {
		logx.Errorf("修改订单主表失败:%s", err.Error())
		if err1 := tx.Rollback(); err1 != nil {
			return "", err1
		}
		return "", errors.New("修改失败")
	}
	// 删除旧的订单详情
	if _, err = dao.OrdersDetailEntity.WithContext(l.ctx).Where(dao.OrdersDetailEntity.OrdersID.Eq(req.Id)).Unscoped().Delete(); err != nil {
		logx.Errorf("删除订单详情失败:%s", err.Error())
		if err1 := tx.Rollback(); err1 != nil {
			return "", err1
		}
		return "", errors.New("修改失败")
	}
	// 订单详情
	var orderDetailList = make([]*model.OrdersDetailEntity, 0)
	for _, item := range req.OrdersDetailList {
		spu := spuMap[item.SpuID]
		spuCount, _ := decimal.NewFromString(item.SpuCount)
		orderDetailList = append(orderDetailList, &model.OrdersDetailEntity{
			OrdersID:                req.Id,                                    // 订单号
			SpuID:                   item.SpuID,                                // 商品id,关联到spu表主键id
			SpuCount:                spuCount,                                  // 商品数量
			SnapshotPrice:           spuPriceMap[item.SpuID],                   // 快照单价
			SpuAmount:               spuCount.Mul(spuPriceMap[item.SpuID]),     // 商品金额小计
			SnapshotName:            k.If(spu != nil, spu.Name, ""),            // 快照商品名称
			SnapshotProductImageURL: k.If(spu != nil, spu.ProductImageURL, ""), // 快照产品图片
			SnapshotCategory:        k.If(spu != nil, spu.CategoryName, ""),    // 快照产品分类
			SnapshotSpuType:         k.If(spu != nil, spu.SpuType, 0),          // 快照产品类型
			SnapshotUnit:            k.If(spu != nil, spu.UnitName, ""),        // 快照产品单位
			SnapshotBrand:           k.If(spu != nil, spu.BrandName, ""),       // 快照品牌
			SnapshotSupplier:        k.If(spu != nil, spu.SupplierName, ""),    // 快照供应商
			Remark:                  item.Remark,                               // 备注
		})
	}
	if err1 := dao.OrdersDetailEntity.WithContext(l.ctx).CreateInBatches(orderDetailList, len(orderDetailList)); err1 != nil {
		logx.Errorf("插入到订单详情失败:%s", err1.Error())
		if err1 := tx.Rollback(); err1 != nil {
			return "", err1
		}
		return "", errors.New("修改失败")
	}
	if err = tx.Commit(); err != nil {
		return "", errors.New("修改失败")
	}
	return "修改成功", nil
}
